package com.fingerchar.api.task;

import cn.hutool.core.collection.CollectionUtil;
import com.fingerchar.api.service.FcUserService;
import com.fingerchar.api.service.TtCalRecordService;
import com.fingerchar.api.service.TtTntInRecordService;
import com.fingerchar.api.service.TtUsdtRechargeService;
import com.fingerchar.core.constant.SysConfConstant;
import com.fingerchar.core.manager.FcSystemConfigManager;
import com.fingerchar.core.util.BigIntegerUtils;
import com.fingerchar.db.dao.ext.FcUserExtMapper;
import com.fingerchar.db.domain.FcUser;
import com.fingerchar.db.domain.TtCalRecord;
import com.fingerchar.db.domain.TtTntInRecord;
import com.fingerchar.db.domain.TtUsdtRecharge;
import com.fingerchar.db.dto.CalSumDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigInteger;
import java.util.List;

/**
 * 算力定时任务
 *
 * @author tangzf
 * @date 2022/9/4
 */
@Configuration
@EnableScheduling
@EnableAsync
@Slf4j
public class CalTask {

    @Resource
    private TtCalRecordService ttCalRecordService;
    @Resource
    private TtTntInRecordService ttTntInRecordService;
    @Resource
    private FcUserService fcUserService;
    @Resource
    private FcSystemConfigManager fcSystemConfigManager;
    @Resource
    private TtUsdtRechargeService ttUsdtRechargeService;
    @Resource
    private FcUserExtMapper fcUserExtMapper;

    /**
     * 每日凌晨0点20分
     * 每日tnt计算(包括tnt递减)
     */
    @Scheduled(cron = "0 20 0 * * ?")
    public void dayCalTntTask() {

        //统计总算力
        List<CalSumDto> calSumDtoList = ttCalRecordService.sumCalByCreateTime(true);
        BigInteger amountAll = calSumDtoList.get(0).getAmount();

        //查询每个人的总算力
        List<CalSumDto> calSumDtos = ttCalRecordService.sumCalByCreateTime(false);
        for (CalSumDto calSumDto : calSumDtos) {
            try {
                processDayCalTnt(calSumDto, amountAll);
            } catch (Exception e) {
                log.error("处理每日tnt计算失败, ", e);
            }
        }
    }

    /**
     * 每日凌晨0点30分
     * 创世用户每日usdt收益
     */
    @Scheduled(cron = "0 30 0 * * ?")
    public void vipCal() {

        //查询vip用户
        List<FcUser> fcUsers = fcUserService.getVipUser();
        if (CollectionUtil.isEmpty(fcUsers)) {
            log.info("没有创世用户");
            return;
        }

        //2、查询平台昨日的usdt收益
        String tntUserAddress = fcSystemConfigManager.getKeyValue(SysConfConstant.TNT_USER_ADDRESS);
        BigInteger usdtAmount = ttUsdtRechargeService.sumByAddressUser(tntUserAddress);
        if (null == usdtAmount || usdtAmount.equals(BigInteger.ZERO)) {
            log.info("平台昨日收益为0");
            return;
        }

        for (FcUser fcUser : fcUsers) {

            try {
                processUsdtVipUser(fcUser, usdtAmount);
            } catch (Exception e) {
                log.error("处理创世收益失败, ", e);
            }

        }
    }

    @Transactional
    public void processDayCalTnt(CalSumDto calSumDto, BigInteger amountAll) {
        BigInteger tntAmount = calSumDto.getAmount().multiply(new BigInteger("531")).divide(amountAll);
        TtTntInRecord tntInRecord = TtTntInRecord.builder()
                .inType("1")
                .tntAmount(tntAmount)
                .orderId(0L)
                .userAddress(calSumDto.getUserAddress())
                .build();
        //增加个人tnt记录
        int row = ttTntInRecordService.addRecord(tntInRecord);
        //增加账户tnt
        int row2 = fcUserService.addTntAmount(calSumDto.getUserAddress(), tntAmount);

        //每日算力递减
        String tnttoUsdtRate = fcSystemConfigManager.getKeyValue(SysConfConstant.TNT_TO_USDT);
        BigInteger calAmount = tntAmount.multiply(new BigInteger(tnttoUsdtRate));
        TtCalRecord ttCalRecord = TtCalRecord.builder()
                .inCalType("3")
                .userAddress(calSumDto.getUserAddress())
                .amount(new BigInteger("-" + calAmount))
                .build();
        //增加个人递减的cal记录
        int ttCalRecordRow = ttCalRecordService.insert(ttCalRecord);
        //减少账户算力
        int ttCalRecordRow2 = fcUserService.reduceCalAmount(calSumDto.getUserAddress(), calAmount);
        if (1 != row || 1 != row2 || 1 != ttCalRecordRow || 1 != ttCalRecordRow2) {
            log.error("tnt每日定时任务失败，记录插入失败");
        }
    }


    @Transactional
    public void processUsdtVipUser(FcUser fcUser, BigInteger usdtAmount) {

        //用户设锁
        fcUser = fcUserService.getLockUserByAddress(fcUser.getAddress());
        //计算vip用户的usdt
        BigInteger userAmount = BigIntegerUtils.mulRate(usdtAmount, fcUser.getVipRate());
        TtUsdtRecharge usdtRecharge = TtUsdtRecharge.builder()
                .amount(userAmount)
                .userAddress(fcUser.getAddress())
                .createTime(System.currentTimeMillis())
                .optType("4")
                .hash("")
                .build();
        //插入vip用户的usdt收益
        int row = ttUsdtRechargeService.insert(usdtRecharge);
        if (1 != row) {
            log.error("创世收益插入失败");
            throw new RuntimeException("创世收益插入失败,userId:" + fcUser.getAddress());
        }
        //给每个用户账号增加usdt收益
        int usdtAmountRow = fcUserService.addUsdtAmount(fcUser.getAddress(), userAmount);
        if (1 != usdtAmountRow) {
            log.error("创世收益增加usdt失败");
            throw new RuntimeException("创世收益增加usdt失败,userId:" + fcUser.getAddress());
        }

    }

}
